// C++ Traits 技术详解
// Traits（特性类）是 C++ 模板元编程中的核心技术，用于在编译期获取、传递或修改类型的特性信息。它是泛型编程的重要工具，让我们能够编写更灵活、更通用的代码。


// ----------------------------------------------------------
// 1. Traits 的基本概念
// Traits 本质上是一种类型函数，它接收一个或多个类型作为输入，然后"返回"与这些类型相关的信息。

// 基本结构
// 通用模板
template<typename T>
struct my_traits {
    // 类型相关信息
    using value_type = typename T::value_type;
    static constexpr bool is_pointer = false;
};

// 特化版本
template<typename T>
struct my_traits<T*> {
    using value_type = T;
    static constexpr bool is_pointer = true;
};

// ----------------------------------------------------------
// 2. Traits 的主要用途
// 2.1 类型信息提取
// 从类型中提取相关信息：
// 迭代器特性类
template<typename Iterator>
struct iterator_traits {
    using value_type = typename Iterator::value_type;
    using difference_type = typename Iterator::difference_type;
    using pointer = typename Iterator::pointer;
    using reference = typename Iterator::reference;
    using iterator_category = typename Iterator::iterator_category;
};

// 针对指针的特化
template<typename T>
struct iterator_traits<T*> {
    using value_type = T;
    using difference_type = std::ptrdiff_t;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;
};
// 这允许我们统一处理迭代器和原始指针。

// 2.2 类型特性检测
// 检测类型是否具有某种特性：
// 检测类型是否可默认构造
template<typename T, typename = void>
struct is_default_constructible : std::false_type {};

template<typename T>
struct is_default_constructible<T, 
    std::void_t<decltype(T())>> : std::true_type {};


// 2.3 类型转换
// 在编译期进行类型转换：
// 移除引用
template<typename T>
struct remove_reference {
    using type = T;
};

template<typename T>
struct remove_reference<T&> {
    using type = T;
};

template<typename T>
struct remove_reference<T&&> {
    using type = T;
};

// C++14 后的便捷别名
template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
